﻿using Microsoft.Activities;
using Microsoft.Workflow.Client;
using Microsoft.Workflow.Samples.Common;
using System;
using System.Activities;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace StateMachineWFM
{
    class Program
    {
        // !!!!!!
        // YOU MUST SET THE baseAddress PROPERTY BELOW TO A FULLY QUALIFIED NAME OF YOUR WORKFLOW MANAGER ENDPOINT
        static string baseAddress = "https://WIN-P08TJ4TPQS4:12290/";
        //static string baseAddress = "http://WIN-P08TJ4TPQS4:12292/";
        static string workflowName_SubscibeActivity = "SubscribeNotification";
        //static string workflowName_StateMachine = "StateMachine";
        static string workflowName_StateMachine = "StateMachineWithDecision";
        // !!!!!!

        static void Main(string[] args)
        {
            Console.Write("Setting up scope...");
            WorkflowManagementClient client = WorkflowUtils.CreateForSample(baseAddress, "StateMachineSample2");
            WorkflowUtils.PrintDone();

            Console.Write("Publishing SubscribeActivity Workflow...");
            client.PublishWorkflow(
                workflowName_SubscibeActivity, @"..\..\..\StateMachineActivityLibrary\SubscribeNotification.xaml");
            WorkflowUtils.PrintDone();

            Console.Write("Publishing StateMachine Workflow...");
            Collection<ExternalVariable> externalVariables = new Collection<ExternalVariable>
            {
                new ExternalVariable<string> { Name = "StateMachineId", Default = "", Modifiers = VariableModifiers.Mapped }
            };
            //client.PublishWorkflow(
            //    workflowName_StateMachine, @"..\..\..\StateMachineActivityLibrary\StateMachine.xaml"
            //    , externalVariables);
            //WorkflowUtils.PrintDone();
            client.PublishWorkflow(
                workflowName_StateMachine, @"..\..\..\StateMachineActivityLibrary\StateMachineWithDecision.xaml"
                , externalVariables);
            WorkflowUtils.PrintDone();

            // Process orders
            bool processing = true;
            while (processing)
            {
                // Console Configuration(s) for readability
                Console.ForegroundColor = ConsoleColor.Gray;

                // Sample Options Menu
                Console.WriteLine("Please enter an option:");
                Console.WriteLine(" [1] Create a Document");
                Console.WriteLine(" [2] Submit a Document");
                Console.WriteLine(" [3] Approve a Document");
                Console.WriteLine(" [4] Reject a Document");
                Console.WriteLine(" [5] Detail of Pending Documents");
                Console.WriteLine(" [6] Cancel of Documents");
                Console.WriteLine(" [7] Detail of Complete Documents");
                Console.WriteLine(" [q] Quit");

                // Console Configuration(s) for readability
                Console.ResetColor();
                var key = Console.ReadKey();
                Console.WriteLine();

                // Switch for sample options
                switch (key.KeyChar)
                {
                    case '1': // Option 1
                        CreateDoc(client);
                        break;
                    case '2': // Option 2
                        SubmitDoc(client);
                        break;
                    case '3': // Option 3
                        ApproveDoc(client);
                        break;
                    case '4': // Option 3
                        RejectDoc(client);
                        break;
                    case '5': // Option 3
                        Details(client);
                        break;
                    case '6':
                        CancelDoc(client);
                        break;
                    case '7':
                        DetailsComplete(client);
                        break;
                    case 'q': // Quit Sample Option
                        processing = false;
                        break;
                    default:
                        break;
                }

                Console.WriteLine();
            }

            client.CleanUp();
        }

        static void CreateDoc(WorkflowManagementClient WFClient)
        {
            
            Console.ForegroundColor = ConsoleColor.Yellow;
            Console.WriteLine("Creating a new document. Please enter ...");
            Console.Write(" [DocumentId]: "); // Document Id
            Console.ForegroundColor = ConsoleColor.White;
            string id = Console.ReadLine();

            Console.Write(" [NeedForApproval] (Y/N): "); // Document Id
            Console.ForegroundColor = ConsoleColor.White;
            string needForApproval = Console.ReadLine();

            Console.Write("Starting workflow instance...");
            WorkflowStartParameters startParameters = new WorkflowStartParameters();
            startParameters.Content.Add("Id", id);
            startParameters.Content.Add("NeedForApproval", needForApproval.ToUpper());
            WFClient.Workflows.Start(workflowName_StateMachine, startParameters);
            WorkflowUtils.PrintDone();
            Console.WriteLine();

        }

        static void SubmitDoc(WorkflowManagementClient WFClient)
        {

            Console.ForegroundColor = ConsoleColor.Yellow;
            Console.WriteLine("Submit a Document. Please enter ...");
            Console.Write(" [DocumentId]: "); // Order Id
            Console.ForegroundColor = ConsoleColor.White;
            string id = Console.ReadLine();
            Console.Write(" Document is Approved (Y/N): "); // Order Id
            Console.ForegroundColor = ConsoleColor.White;
            string approved = Console.ReadLine();

            // Publish New Order message (via OrderTally Workflow) 
            WFClient.PublishNotification(new WorkflowNotification()
            {
                Properties =
                {
                    { "EventName", "Submit" },
                    { "Id", id }
                },
                Content = new Dictionary<string, object>()
                {
                    {"myvar", approved.ToUpper()}
                }
            });

        }

        static void ApproveDoc(WorkflowManagementClient WFClient)
        {

            Console.ForegroundColor = ConsoleColor.Yellow;
            Console.WriteLine("Submit a Document. Please enter ...");
            Console.Write(" [DocumentId]: "); // Order Id
            Console.ForegroundColor = ConsoleColor.White;
            string id = Console.ReadLine();

            // Publish New Order message (via OrderTally Workflow) 
            WFClient.PublishNotification(new WorkflowNotification()
            {
                Properties =
                {
                    { "EventName", "Approve" },
                    { "Id", id }
                },
                Content = new Dictionary<string, object>()
                {
                }
            });
            
        }

        static void RejectDoc(WorkflowManagementClient WFClient)
        {

            Console.ForegroundColor = ConsoleColor.Yellow;
            Console.WriteLine("Reject a Document. Please enter ...");
            Console.Write(" [DocumentId]: "); // Order Id
            Console.ForegroundColor = ConsoleColor.White;
            string id = Console.ReadLine();

            // Publish New Order message (via OrderTally Workflow) 
            WFClient.PublishNotification(new WorkflowNotification()
            {
                Properties =
                {
                    { "EventName", "Reject" },
                    { "Id", id }
                },
                Content = new Dictionary<string, object>()
                {
                }
            });

        }

        static void CancelDoc(WorkflowManagementClient WFClient)
        {
            Console.ForegroundColor = ConsoleColor.Yellow;
            Console.WriteLine("Reject a Document. Please enter ...");
            Console.Write(" [DocumentId]: "); // Order Id
            Console.ForegroundColor = ConsoleColor.White;
            string id = Console.ReadLine();

            // Publish New Order message (via OrderTally Workflow) 
            WFClient.PublishNotification(new WorkflowNotification()
            {
                Properties =
                {
                    { "EventName", "Cancel" },
                    { "Id", id }
                },
                Content = new Dictionary<string, object>()
                {
                }
            });
        }


        static void Details(WorkflowManagementClient WFClient)
        {
            // Print ProcessOrder stats
            var completedSM = WFClient.Instances.Get(0, 100, workflowName_StateMachine, Microsoft.Activities.WorkflowInstanceStatus.Completed);
            Console.WriteLine("Completed Orders: {0}", completedSM.Count);
            var pendingSM = WFClient.Instances.Get(0, 100, workflowName_StateMachine, Microsoft.Activities.WorkflowInstanceStatus.Started);
            Console.WriteLine("Pending Orders: {0}", pendingSM.Count);
            foreach (var sm in pendingSM)
            {

                Console.WriteLine(" ------------------- ");
                Console.WriteLine(" [CreationTime]: {0}", sm.CreationTime);
                Console.WriteLine(" [LastModified]: {0}", sm.LastModified);
                Console.WriteLine(" [InstanceName]: {0}", sm.InstanceName);
                Console.WriteLine(" [ScopePath]: {0}", sm.ScopePath);
                Console.WriteLine(" [WorkflowName]: {0}", sm.WorkflowName);
                Console.WriteLine(" [WorkflowStatus]: {0}", sm.WorkflowStatus);
                Console.WriteLine(" [WorkflowStatusDetails]: {0}", sm.WorkflowStatusDetails);
                Console.WriteLine(" [UserStatus]: {0}", sm.UserStatus);
                try
                {
                    Console.WriteLine(" [StateMachineId]: {0}"
                        , sm.MappedVariables["{http://schemas.microsoft.com/workflow/2012/xaml/activities/externalvariable}StateMachineId"]);
                }
                catch (Exception e) { }
            }

            Console.ResetColor();
        }

        static void DetailsComplete(WorkflowManagementClient WFClient)
        {
            // Print ProcessOrder stats
            var completedSM = WFClient.Instances.Get(0, 100, workflowName_StateMachine, Microsoft.Activities.WorkflowInstanceStatus.Completed);
            Console.WriteLine("Completed Orders: {0}", completedSM.Count);
            foreach (var sm in completedSM)
            {

                Console.WriteLine(" ------------------- ");
                Console.WriteLine(" [CreationTime]: {0}", sm.CreationTime);
                Console.WriteLine(" [LastModified]: {0}", sm.LastModified);
                Console.WriteLine(" [InstanceName]: {0}", sm.InstanceName);
                Console.WriteLine(" [ScopePath]: {0}", sm.ScopePath);
                Console.WriteLine(" [WorkflowName]: {0}", sm.WorkflowName);
                Console.WriteLine(" [WorkflowStatus]: {0}", sm.WorkflowStatus);
                Console.WriteLine(" [WorkflowStatusDetails]: {0}", sm.WorkflowStatusDetails);
                Console.WriteLine(" [UserStatus]: {0}", sm.UserStatus);
                try
                {
                    Console.WriteLine(" [StateMachineId]: {0}"
                        , sm.MappedVariables["{http://schemas.microsoft.com/workflow/2012/xaml/activities/externalvariable}StateMachineId"]);
                }
                catch (Exception e) { }
            }

            Console.ResetColor();
        }       

    }
}
